import { constantRouterMap } from '@/config/router.config'
import { getNavigators } from '@/api/user'
import _store from 'store2'
import _ from 'lodash'
import BasicLayoutGroup from '@/components/Layout/BasicLayoutGroup'

let asyncRouterMap = []
window.config.VUE_APP_NAME.split(',').forEach(function (item) {
  asyncRouterMap.push({
    path: '/',
    name: item,
    component: BasicLayoutGroup
  })
})

const allRoutes = [].concat(asyncRouterMap, (constantRouterMap || []))

/**
 * 检查路由是否为正确路由
 * @param routes
 * @param path
 */
function findRouteByPath (routes, path) {
  for (const item of routes) {
    if (item.path === path) {
      return item
    }
    if (item.children && item.children.length > 0) {
      const res = findRouteByPath(item.children, path)
      if (res) {
        return res
      }
    }
  }
}

/**
 * 根据权限，过滤出有权限的路由
 * @param routerMap
 * @param permissionList
 * @param map
 * @returns {*}
 */

function generate (routerMap, permissionList, map) {
  const accessedRouter = routerMap.filter(route => {
    if (checkRouterAuth(route, permissionList, map) || route.children) {
      if (route.children) {
        route.children = generate(route.children, permissionList, map)
      } else {
        return true
      }
      return checkParentRouteAuth(route)
    }
    return false
  })
  return accessedRouter
}

/**
 * 自由路由
 * 当父级路由配置权限，但是配置了子路由的权限时，
 * 检查父路由的 children.length 是否大于 0；
 * 大于 0 的时候可能是包含不需要控制权限的路由表，
 * 如果过滤出来的 children 全部是不需要控制权限的路由表的时候，该路由不应该有权限注册
 * 反之注册该路由
 * @param route
 */
function checkParentRouteAuth (route) {
  for (const item of route.children) {
    if (item.needAuth !== false) return true
  }
  return false
}

/**
 * 1、根路由默认有权限
 * 2、当路由中没有 needAuth，或者 needAuth = true 的时候，认为需要进行权限判断
 * 反之，如果 needAuth = false 的时候，认为该路由是有权限访问
 * 3、将有权限的路由信息添加至 map 中，便于后续生成导航栏信息
 * @param route
 * @param permissionList
 * @returns {boolean}
 */
function checkRouterAuth (route, permissionList, map) {
  if (route.path === '/') return true
  if (!route.needAuth && route.needAuth === false) return true
  if (route.meta && route.meta.rightName) {
    const flag = checkPermission(route, permissionList)
    if (flag) {
      map.set(route.meta.id, {
        name: route.meta.title,
        routerName: route.name,
        icon: route.meta.icon,
        redirect: route.redirect,
        group: route.meta.group,
        id: route.meta.id
      })
    }
    return flag
  }
  return false
}

/**
 * 遍历检查当前路由是否有权限
 * 权限表已扁平化
 */
function checkPermission (route, permissionList) {
  for (const item of permissionList) {
    if (item.name === route.meta.rightName) {
      return true
    }
  }
  return false
}

/**
 * 生成导航栏信息
 * 1、遍历权限列表
 * 2、通过前面生成的 map，将 map 的信息添加至合并进导航栏中去
 * @param menuList
 * @param map
 */
function generateMenu (menuList, map) {
  for (const menu of menuList) {
    if (menu.children) {
      generateMenu(menu.children, map)
    }
    if (map.has(menu.id)) {
      Object.assign(menu, map.get(menu.id))
    }
  }
}

/**
 * 数组扁平化
 * @param arr
 * @returns {*}
 */
function flatten (arr) {
  return arr.reduce((pre, cur) => {
    if (Array.isArray(cur.children)) {
      const c = _.cloneDeep(cur)
      delete c.children
      pre.push(c)
      return pre.concat(flatten(cur.children))
    } else {
      return pre.concat(cur)
    }
  }, [])
}

/**
 * 转为菜单树
 * @param {Array} list
 * @returns {Array}
 */
function getTreeMenu (list) {
  list = JSON.parse(JSON.stringify(list))
  if (!list || !(list instanceof Array) || list.length === 0) {
    return []
  }
  list = list.filter(item => item.type !== 'app')
  const obj = {}
  const result = []
  for (let i = 0; i < list.length; i++) {
    obj[list[i].id] = list[i]
  }
  for (let j = 0; j < list.length; j++) {
    if (list[j].type === 'model') {
      result.push(list[j])
    } else {
      if (!obj[list[j].parentId].children) {
        obj[list[j].parentId].children = []
      }
      obj[list[j].parentId].children.push(list[j])
    }
  }
  return result
}

/**
 * 将菜单树转为菜单JSON对象数据
 * @param {Array} list
 */
function getMenuJson (list) {
  const treeMenu = getTreeMenu(list)
  const getMenu = (treeList) => {
    const resultList = []
    treeList.forEach(item => {
      if (item.componentType !== 'XMMX') {
        const data = {
          name: item.name,
          id: item.id,
          desc: item.desc,
          url: item.url,
          digitalTag: item.digitalTag,
          matterType: item.matterType
        }
        if (item.children) {
          data.children = getMenu(item.children)
        }
        resultList.push(data)
      }
    })
    return resultList
  }
  const resultTree = getMenu(treeMenu)
  return { menuList: resultTree }
}

function getAsyncRouterMap (name, list) {
  const treeMenu = getTreeMenu(list)
  const reports = treeMenu.filter((item) => item.componentType === 'TJBB')
  let temp = []
  if (reports.length === 0) {
    temp = getRouter(treeMenu)
  } else {
    const tempMenu = treeMenu.filter((item) => item.componentType !== 'TJBB')
    temp = getRouter(tempMenu)
    reports.forEach(item => {
      const index = treeMenu.findIndex(item1 => item.id === item1.id)
      const statisticsReportRouter = getStatisticsReportsRouter(treeMenu[index])
      temp.splice(index, 0, statisticsReportRouter)
    })
  }
  asyncRouterMap.forEach(function (item) {
    if (item.name === name) {
      item.children = temp
    }
  })
  return asyncRouterMap
}

/**
 * 正常路由处理
 * @param {Array} treeList
 * @returns
 */
function getRouter (treeList, modelId = '') {
  const resultList = []
  const RouteView = {
    name: 'RouteView',
    render: (h) => h('router-view')
  }
  treeList.forEach(item => {
    if (item.type === 'model') {
      modelId = item.id
    }
    let routerPath = item.routerPath
    if (item.routerParam) {
      if (item.routerParam.substr(0, 1) === '/') {
        routerPath += item.routerParam
      } else {
        routerPath = '/' + item.routerParam
      }
    }
    const data = {
      path: routerPath,
      name: item.routerName,
      meta: { title: item.name, rightName: item.name, group: item.routerGroup, keepAlive: true, icon: item.icon, id: item.id, digitalTag: item.digitalTag, matterType: item.matterType, desc: item.desc }
    }
    if (item.children) {
      data.redirect = item.children[0].routerPath
      data.component = RouteView
      const temp = getRouter(item.children, modelId)
      data.children = temp
    } else {
      data.meta.modelId = modelId
      if (item.componentType === 'DLWY') {
        data.component = resolve => { require(['@/views/Iframe/Iframe'], resolve) }
        data.meta.pathUrl = item.url
      } else if (item.componentType === 'XMMX' && item.routerParam && item.routerParam.includes('detail')) {
        data.meta.keepAlive = undefined
        data.meta.pageType = 'iframeForm'
        data.iframeComponent = resolve => { require(['@/views' + item.component], resolve) }
      } else {
        data.component = resolve => { require(['@/views' + item.component], resolve) }
      }
      if (item.componentType === 'XMMX') {
        data.needAuth = false
      }
    }
    resultList.push(data)
  })
  return resultList
}

/**
 * 统计报表路由处理
 * @param {Object} obj
 */
function getStatisticsReportsRouter (obj) {
  const RouteView = {
    name: 'RouteView',
    render: (h) => h('router-view')
  }
  const result = {
    path: obj.routerPath,
    name: obj.routerName,
    meta: { title: obj.name, rightName: obj.name, group: obj.routerGroup, keepAlive: true, icon: obj.icon, id: obj.id },
    component: RouteView
  }
  const routerChildren = (list, tPath, tFlag) => {
    const resultList = []
    list.forEach((item, index) => {
      const tempName = tFlag + '-' + index
      const tempPath = tPath + '/' + item.id
      let data = {}
      if (item.component != undefined) {
        data = {
          path: item.routerPath,
          name: item.routerName,
          meta: { title: item.name, rightName: item.name, group: item.routerGroup, keepAlive: true, icon: item.icon }
        }
      } else {
        data = {
          path: obj.routerPath + tempPath,
          name: obj.routerName + tempName,
          meta: { title: item.name, rightName: item.name, group: obj.routerGroup, keepAlive: true, icon: obj.icon, id: item.id }
        }
      }
      if (item.children) {
        data.component = RouteView
        const temp = routerChildren(item.children, tempPath, tempName)
        data.children = temp
      } else {
        if (item.component !== undefined) {
          data.component = resolve => { require(['@/views' + item.component], resolve) }
          if (!item.isShow) {
            data.needAuth = false
          }
        }
      }
      resultList.push(data)
    })
    return resultList
  }

  result.children = routerChildren(obj.children, '', 0)
  result.redirect = result.children[0].path
  return result
}

// 获取所有页面路由
function getAllPageRouter (obj) {
  const apps = JSON.parse(JSON.stringify(obj))
  const pages = []
  for (const key in apps) {
    pages.push({ name: key, children: getTreeMenu(apps[key]) })
  }
  return pages
}

const initState = {
  routers: constantRouterMap,
  addRouters: [],
  navList: [],
  menuList: [],
  authList: [],
  updatePackage: []
}
_store({ permissionInitState: initState })

const state = {
  ...initState,
  initState () {
    return _store('permissionInitState')
  }
}

const permission = {
  state,
  mutations: {
    SET_NAV: (state, navList) => {
      state.navList = navList
    },
    SET_ROUTERS: (state, routers) => {
      state.addRouters = routers
      state.routers = constantRouterMap.concat(routers)
    },
    SET_MENU: (state, menuList) => {
      state.menuList = menuList
    },
    SET_MENUMAP: (state, menuList) => {
      state.menuMap = menuList
    },
    SET_AUTH: (state, authList) => {
      state.authList = authList
    },
    UPDATE_PACKAGE_UPDATE_DATA: (state, updatePackage) => {
      state.updatePackage = updatePackage
    }
  },
  actions: {
    GenerateRoutes ({ commit }, data) {
      return new Promise(resolve => {
        getNavigators().then(res => {
          const keys = Object.keys(res)
          // console.log(0, res)
          let menuList = []
          const menuMap = {}
          keys.forEach(function (key) {
            const resp = res[key]
            const menu = getMenuJson(resp)

            asyncRouterMap = getAsyncRouterMap(key, resp)
            menuList = menuList.concat(menu.menuList)
            menuMap[key] = menu.menuList
          })
          // console.log(1, menuMap)
          const map = new Map()
          generate(asyncRouterMap, flatten(menuList), map) // 根据权限生成路由表

          // 默认重定向到第一个模块，如果配置了就走配置模块
          if (asyncRouterMap[0].children.length > 0) {
            const initModel = window.config.VUE_APP_INIT_MODEL || ''
            if (initModel) {
              const tresve = (array, target) => {
                for (let i = 0; i < array.length; i++) {
                  const item = array[i]
                  if (item.meta.rightName === target) {
                    return (item.redirect || item.path)
                  }
                  if (item.children && item.children.length > 0) {
                    const res = tresve(item.children, target)
                    if (res) {
                      return res
                    }
                  }
                }
                return ''
              }
              asyncRouterMap[0].redirect = tresve(asyncRouterMap[0].children, initModel)
            } else {
              asyncRouterMap[0].redirect = asyncRouterMap[0].children[0].redirect
            }
          }

          generateMenu(menuList, map) // 生成导航栏
          commit('SET_MENUMAP', menuMap)
          commit('SET_ROUTERS', asyncRouterMap)
          resolve()
        })
      })
    },
    CheckRoute ({ commit }, data) {
      return new Promise(resolve => {
        const res = findRouteByPath(allRoutes, data)
        resolve(res)
      })
    }
  }
}

export default permission
